//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using System;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;

namespace EntLibContrib.Mapping.Configuration.Design
{
	/// <summary>
	/// This class builds the hierarchy node structure from an existing configuration
	/// to populate the console from configuration data.
	/// </summary>
	public class MappingSettingsNodeBuilder : NodeBuilder
	{
		#region Fields
		private MappingSettings mappingSettings;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="MappingSettingsNodeBuilder"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="mappingSettings">The mapping settings.</param>
		public MappingSettingsNodeBuilder(IServiceProvider serviceProvider, MappingSettings mappingSettings)
			: base(serviceProvider)
		{
			this.mappingSettings = mappingSettings;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Builds this instance.
		/// </summary>
		/// <returns></returns>
		public MappingSettingsNode Build()
		{
			MappingSettingsNode rootNode = new MappingSettingsNode();

			// build the mapper nodes
			foreach (MapperBaseData mapperData in mappingSettings.Mappers)
			{
				BuildMapperNode(rootNode, mapperData);
			}

			// set the require permission mode
			rootNode.RequirePermission = mappingSettings.SectionInformation.RequirePermission;
			return rootNode;
		}
		#endregion

		#region Private Methods
		private void BuildMapperNode(MappingSettingsNode rootNode, MapperBaseData mapperData)
		{
			ConfigurationNode mapperNode = NodeCreationService.CreateNodeByDataType(mapperData.GetType(), new object[] { mapperData });
			if (mapperNode == null)
				LogNodeMapError(rootNode, mapperData.GetType());

			rootNode.AddNode(mapperNode);

			// special case for mapper nodes based on MapperNode
			MapperNode node = mapperNode as MapperNode;
			if (node != null)
			{
				// build the map nodes
				foreach (MapData mapData in ((MapperData)mapperData).Maps)
				{
					BuildMapNode(mapperNode, mapData);
				}
			}
		}

		private void BuildMapNode(ConfigurationNode mapperNode, MapData mapData)
		{
			ConfigurationNode mapNode = NodeCreationService.CreateNodeByDataType(mapData.GetType(), new object[] { mapData });
			if (null == mapNode)
				LogNodeMapError(mapperNode, mapData.GetType());

			mapperNode.AddNode(mapNode);
		}
		#endregion
	}
}